package com.dlx.activity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlx.acl.client.UserFeignClient;
import com.dlx.activity.mapper.RechargeActivityMapper;
import com.dlx.activity.service.RechargeActivityService;
import com.dlx.common.exception.SmmsException;
import com.dlx.model.acl.User;
import com.dlx.model.activity.RechargeActivity;
import com.dlx.vo.activity.RechargeActivityQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author nglon
 * @since 2021-11-17
 */
@Service
public class RechargeActivityServiceImpl extends ServiceImpl<RechargeActivityMapper, RechargeActivity> implements RechargeActivityService {

    @Autowired
    private UserFeignClient userFeignClient;

    @Override
    public RechargeActivity show(Long id) {
        RechargeActivity rechargeActivity = this.baseMapper.selectById(id);
        packageRechargeActivity(rechargeActivity);
        return rechargeActivity;
    }

    @Override
    public Page<RechargeActivity> selectRechargeActivityPage(Long current, Long limit, RechargeActivityQueryVo rechargeActivityQueryVo) {
        Page<RechargeActivity> page = new Page<>(current, limit);
        QueryWrapper<RechargeActivity> wrapper = new QueryWrapper<>();
        if (rechargeActivityQueryVo.getId() != null) {
            wrapper.like("id", rechargeActivityQueryVo.getId());
        }
        if (rechargeActivityQueryVo.getCreatorId() != null) {
            wrapper.like("creator_id", rechargeActivityQueryVo.getCreatorId());
        }
        if (rechargeActivityQueryVo.getRechargeAmount() != null) {
            wrapper.gt("recharge_amount", rechargeActivityQueryVo.getRechargeAmount());
        }
        if (rechargeActivityQueryVo.getGiftPoints() != null) {
            wrapper.gt("gift_points", rechargeActivityQueryVo.getGiftPoints());
        }
        if (rechargeActivityQueryVo.getStartTime() != null) {
            wrapper.ge("start_time", rechargeActivityQueryVo.getStartTime());
        }
        if (rechargeActivityQueryVo.getEndTime() != null) {
            wrapper.le("end_time", rechargeActivityQueryVo.getEndTime());
        }
        if (rechargeActivityQueryVo.getStatus() != null) {
            if (rechargeActivityQueryVo.getStatus() == -1) {
                wrapper.eq("is_discarded", 1);
            } else if (rechargeActivityQueryVo.getStatus() == 0) {
                wrapper.gt("start_time", LocalDateTime.now());
            } else if (rechargeActivityQueryVo.getStatus() == 1) {
                wrapper.le("start_time", LocalDateTime.now());
                wrapper.ge("end_time", LocalDateTime.now());
            } else if (rechargeActivityQueryVo.getStatus() == 2) {
                wrapper.lt("end_time", LocalDateTime.now());
            }
        }
        Page<RechargeActivity> rechargeActivityPage = this.baseMapper.selectPage(page, wrapper);
        rechargeActivityPage.getRecords().forEach(this::packageRechargeActivity);
        return rechargeActivityPage;
    }

    @Override
    public Boolean add(RechargeActivity rechargeActivity) {
        this.ifExistActivity(rechargeActivity);
        rechargeActivity.setCreatorId(this.userFeignClient.getCurrentUser().getId());
        int insert = this.baseMapper.insert(rechargeActivity);
        return insert > 0;
    }

    @Override
    public Boolean updateRechargeActivity(RechargeActivity rechargeActivity) {
        ifExistActivity(rechargeActivity);
        int i = this.baseMapper.updateById(rechargeActivity);
        return i > 0;
    }

    @Override
    public RechargeActivity whetherInActivityTime(LocalDateTime currentTime) {
        QueryWrapper<RechargeActivity> wrapper = new QueryWrapper<>();
        wrapper.eq("is_discarded",0)
                .le("start_time",currentTime)
                .ge("end_time",currentTime);
        List<RechargeActivity> rechargeActivities = this.baseMapper.selectList(wrapper);
        if(rechargeActivities.size() != 1){
            return null;
        }else{
            return rechargeActivities.get(0);
        }
    }

    private void packageRechargeActivity(RechargeActivity rechargeActivity) {
        User creatorUser = this.userFeignClient.getById(rechargeActivity.getCreatorId());
        rechargeActivity.getParam().put("creatorUsername", creatorUser.getUsername());
        rechargeActivity.getParam().put("stringStatus", getStringStatus(rechargeActivity));
    }

    private String getStringStatus(RechargeActivity rechargeActivity) {
        if (rechargeActivity.getIsDiscarded() == 1) {
            return "已禁用";
        } else if (rechargeActivity.getStartTime().compareTo(LocalDateTime.now()) > 0) {
            return "未开始";
        } else if (rechargeActivity.getStartTime().compareTo(LocalDateTime.now()) <= 0 && rechargeActivity.getEndTime().compareTo(LocalDateTime.now()) > 0) {
            return "已开始";
        } else if (rechargeActivity.getEndTime().compareTo(LocalDateTime.now()) <= 0) {
            return "已结束";
        }
        return "未开始";
    }

    /**
     * 如果存在活动
     *
     * @param rechargeActivity 充值活动
     */
    private void ifExistActivity(RechargeActivity rechargeActivity) {
        if(rechargeActivity.getStartTime().compareTo(rechargeActivity.getEndTime())>0){
            throw new SmmsException(201,"活动开始时间必须小于活动结束时间");
        }
        QueryWrapper<RechargeActivity> wrapper = new QueryWrapper<>();
        if(rechargeActivity.getId()!=null){
            wrapper.ne("id",rechargeActivity.getId());
        }
        wrapper.eq("is_discarded", 0)
                .nested(i->i
                        .nested(j->j.ge("end_time", rechargeActivity.getStartTime()).le("start_time",rechargeActivity.getStartTime()))
                        .or()
                        .nested(j->j.ge("end_time", rechargeActivity.getEndTime()).le("start_time",rechargeActivity.getEndTime()))
                        .or()
                        .nested(j->j.ge("start_time",rechargeActivity.getStartTime()).le("end_time",rechargeActivity.getEndTime())))
        ;
        List<RechargeActivity> rechargeActivities = this.baseMapper.selectList(wrapper);
        if (!rechargeActivities.isEmpty()) {
            throw new SmmsException(201, "当前时间段已存在其他活动");
        }
    }
}
